package org.budo.support.http.client;

import java.io.File;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.budo.support.lang.util.IoUtil;
import org.budo.support.lang.util.NumberUtil;
import org.budo.support.mvcs.Mvcs;
import org.budo.support.servlet.util.QueryStringUtil;
import org.budo.support.slf4j.Slf4j;
import org.slf4j.Logger;

/**
 * @author li (limingwei@mail.com)
 * @version 1 (2013年12月16日 下午1:53:39)
 */
@SuppressWarnings({ "rawtypes", "unchecked" })
public class HttpUtil {
    private static final Logger log = Slf4j.getLogger();

    public static Response get(String url) {
        log.debug("#17 get() url={}", url);

        Request request = new Request();
        request.setUrl(url);
        return request.execute();
    }

    public static Response post(String url, byte[] data) {
        return post(url, null, data);
    }

    public static Response post(String url) {
        return post(url, null, null);
    }

    public static Response post(String url, byte[] bytes, String contentType, String userAgent) {
        Request request = new Request();
        request.setUrl(url);
        request.setMethod(Request.POST);
        request.setRequestBody(bytes);
        request.setContentType(contentType);
        request.setHeader("User-Agent", userAgent);
        return request.execute();
    }

    public static Response post(String url, Map fields) {
        return post(url, fields, null);
    }

    /**
     * 有 fields 时 不会用 data
     */
    public static Response post(String url, Map fields, byte[] data) {
        Request request = new Request();
        request.setUrl(url);
        request.setMethod(Request.POST);

        if (null != fields) {
            request.setFields(fields);
        } else {
            request.setRequestBody(data);
        }

        return request.execute();
    }

    public static Response postJson(String url, String requestBody) {
        Request request = new Request();
        request.setUrl(url);
        request.setMethod(Request.POST);

        request.setRequestBody(requestBody);

        request.setContentType("application/json");

        return request.execute();
    }

    public static void replayRequest(HttpServletRequest request, String url) {
        String contentType = Mvcs.getContentType(request);
        String requestBody = Mvcs.getRequestBody(request);

        String queryString = QueryStringUtil.mapToQueryString(Mvcs.getRequestParameterMap(request));
        String _url = url + "?" + queryString;

        Request req = new Request();
        req.setUrl(_url);
        req.setContentType(contentType);
        req.setRequestBody(requestBody);

        try {
            Response response = req.execute();

            log.info("#80 after replayRequest, _url=" + _url + ", response=" + response);
        } catch (Throwable e) {
            log.error("#82 replayRequest error, _url=" + _url + ", requestBody = " + requestBody + ", e=" + e, e);
        }
    }

    public static boolean ok_200(String url, Integer connectTimeout, Integer readTimeout) {
        if (null == url || url.trim().isEmpty()) {
            log.error("#105 not ok, url=" + url);
            return false;
        }

        try {
            Request request = new Request();
            request.setUrl(url);
            request.setMethod(Request.POST);
            request.setConnectTimeout(connectTimeout);
            request.setReadTimeout(readTimeout);

            Response response = request.execute();
            log.debug("#111 url is ok, url={}, response={}", url, response);

            if (!NumberUtil.equals(200, response.getStatus())) {
                log.warn("#120 not ok, url=" + url + ", response=" + response);
                return false;
            }

            return true;
        } catch (Throwable e) {
            log.warn("#126 not ok, url=" + url + ", e=" + e);
            return false;
        }
    }

    public static Boolean ok_200(String url) {
        int connectTimeout = 500;
        int readTimeout = 1000;
        return ok_200(url, connectTimeout, readTimeout);
    }

    public static Boolean ok(String url) {
        if (null == url || url.trim().isEmpty()) {
            log.error("#102 not ok, url=" + url);
            return false;
        }

        try {
            Request request = new Request();
            request.setUrl(url);
            request.setMethod(Request.POST);
            request.setConnectTimeout(1000);
            request.setReadTimeout(3000);

            Response response = request.execute();
            log.debug("#111 url is ok, url={}, response={}", url, response);

            if (NumberUtil.equals(502, response.getStatus())) {
                return false;
            }

            return true;
        } catch (Throwable e) {
            log.error("#109 not ok, url=" + url + ", e=" + e);
            return false;
        }
    }

    public static void download(String url, File file) {
        Response response = get(url);
        IoUtil.write(response.getResponseData(), file);
    }
}